#include "ecb/benchmarks/mpb/PeakFunctionTwin.h"


#include "ecb/base/Math.h""
#include <math.h>

namespace ecb {

    namespace mpb {

        PeakFunctionTwin::PeakFunctionTwin() { }

        PeakFunctionTwin::~PeakFunctionTwin() { }

        scalar PeakFunctionTwin::f(const std::vector<scalar>& x, const Matrix2D& peaks, int peakIndex) {

            int j;
            scalar maximum = -INFINITY, dummy;
            /* difference to first peak */
            /*static*/
            double twin_peak[] = {1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0};

            dummy = Math::Pow2(x[0] - peaks[peakIndex][0]);
            for (j = 1; j < x.size(); j++) {
                dummy += Math.Pow2(x[j] - peaks[peakIndex][j]);
            }
            dummy =
                    peaks[peakIndex][x.size() + 1]
                    - (peaks[peakIndex][x.size()] * dummy);
            maximum = dummy;
            //System.out.println("j: "+j);
            dummy = Math.Pow2(x[j] - (peaks[peakIndex][0] + twin_peak[0]));
            for (j = 1; j < x.size(); j++) {
                dummy += Math.Pow2(x[j] - (peaks[peakIndex][j] + twin_peak[0]));
            }
            dummy = peaks[peakIndex][x.size() + 1] + twin_peak[x.size() + 1]
                    - ((peaks[peakIndex][x.size()] + twin_peak[x.size()]) * dummy);

            if (dummy > maximum) {
                maximum = dummy;
            }

            return maximum;
        }

        std::string PeakFunctionTwin::toString() const {
            return "PeakFunctionTwin";
        }

    }
}
